use salvo::writing::Json;
use salvo::{async_trait, Depot, Request, Response, Writer};
use serde::Serialize;
use std::error::Error;


#[async_trait]
impl<T: Serialize + Sync + Send> Writer for ApiResult<T> {
    async fn write(self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
        res.render(Json(self))
    }
}

// 为 ApiResult 实现 From<Error>，便于与 ? 运算符兼容
impl<T: Serialize + Sync + Send> From<anyhow::Result<T, anyhow::Error>> for ApiResult<T> {
    fn from(result: Result<T, anyhow::Error>) -> Self {
        match result {
            Ok(data) => ApiResult::success(data),
            Err(err) => ApiResult::error(err),
        }
    }
}


#[derive(Debug, Serialize)]
pub struct ApiResult<T> {
    pub code: i32,
    pub data: Option<T>,
    pub msg: String,
}

impl<T: Serialize + Send + Sync + Sized> ApiResult<T> {
    pub fn std_error(err: Box<dyn Error>) -> Self {
        Self {
            code: 500,
            data: None,
            msg: err.to_string(),
        }
    }
    pub fn error(error: anyhow::Error) -> Self {
        Self {
            code: 400,
            data: None,
            msg: error.to_string(),
        }
    }

    pub fn success(data: T) -> Self {
        Self {
            code: 200,
            data: Some(data),
            msg: "success".to_string(),
        }
    }
    #[allow(dead_code)]
    pub fn success_msg(data: T, msg: &str) -> Self {
        Self {
            code: 0,
            data: Some(data),
            msg: msg.to_string(),
        }
    }
}


//pub struct ApiWriter<T>(pub anyhow::Result<T>);


//
// #[async_trait]
// impl<T: Serialize + Sync + Send> Writer for ApiWriter<T> {
//     async fn write(self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
//         match self.0 {
//             Ok(data) => res.render(Json(ApiResult {
//                 code: 200,
//                 data: Some(data),
//                 msg: "success".to_string(),
//             })),
//             Err(e) => res.render(Json(ApiResult::<()> {
//                 code: 500,
//                 data: None,
//                 msg: e.to_string(),
//             })),
//         }
//     }
// }

// impl<T: Serialize> From<anyhow::Result<T>> for ApiResult<T> {
//     fn from(value: anyhow::Result<T>) -> Self {
//         match value {
//             Ok(data) => ApiResult {
//                 code: 200,
//                 data: Some(data),
//                 msg: "success".to_string(),
//             },
//             Err(e) => ApiResult {
//                 code: 500,
//                 data: None,
//                 msg: e.to_string(),
//             },
//         }
//     }
// }


// 为 ApiResult 实现 From<Error>
// impl<T> From<anyhow::Error> for ApiResult<T> {
//     fn from(err: anyhow::Error) -> Self {
//         ApiResult {
//             code: 500,
//             data: None,
//             msg: err.to_string(),
//         }
//     }
// }


// impl<T> From<anyhow::Result<T>> for ApiWriter<T> {
//     fn from(result: anyhow::Result<T>) -> Self {
//         ApiWriter(result)
//     }
// }